package com.xiaomengkuan.user.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.xiaomengkuan.common.entity.vo.PageVo;
import com.xiaomengkuan.common.exception.CasualException;
import com.xiaomengkuan.common.exception.LoginFailedException;
import com.xiaomengkuan.common.exception.RequestBodyArgumentException;
import com.xiaomengkuan.common.util.DetailSelector;
import com.xiaomengkuan.common.util.R;
import com.xiaomengkuan.common.util.YsjUtil;
import com.xiaomengkuan.user.entity.pojo.User;
import com.xiaomengkuan.user.entity.vo.UserResponseVo;
import com.xiaomengkuan.user.mapper.UserMapper;
import com.xiaomengkuan.user.service.UserService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.RandomUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import javax.annotation.Resource;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import java.util.stream.Collectors;

import static com.xiaomengkuan.common.util.YsjUtil.*;

/**
 * 用户Service实现类
 *
 * @author Faraj Mujey
 * -- Creation Time: 2021-01-25 11:05 下午, File Encoding: utf8 --
 */
@Slf4j
@Service
public class UserServiceImpl implements UserService {

    private final String DEFAULT_AVATAR_BASE_URL = "https://sayclothes-avatar" +
            ".oss-cn-hangzhou.aliyuncs.com/";

    @Resource
    private UserMapper userMapper;

    /**
     * 用户名密码登陆接口实现
     *
     * @param requestBody 用户名、密码
     * @return UserResponseVo
     */
    @Override
    public UserResponseVo passwordLogin(Map<String, Object> requestBody) {
        checkRequestBodyForPassword(requestBody);
        String username = (String) requestBody.get("username");
        // 找到用户数据
        QueryWrapper<User> userQueryWrapper = new QueryWrapper<>();
        User targetUser = userMapper.selectOne(userQueryWrapper.eq("username",
                username));
        if (targetUser == null) throw new LoginFailedException(5000,
                "用户尚未注册，请通过手机号登录注册");
        String password = (String) requestBody.get("password");
        boolean success = targetUser.getPassword().equals(password);
        if (success) {
            UserResponseVo userResponseVo = new UserResponseVo();
            BeanUtils.copyProperties(targetUser, userResponseVo);
            return userResponseVo;
        }
        throw new LoginFailedException(5000, "用户名或密码错误");
    }

    /**
     * 手机号登陆接口实现
     *
     * @param requestBody 手机号、验证码
     * @return UserResponseVo
     */
    @Override
    public UserResponseVo phoneLogin(Map<String, Object> requestBody) {
        // TODO: 验证验证码是否正确 < 2021-02-07, farajmujey > 📣
        String phone = (String) requestBody.get("phone");
        if (!StringUtils.isEmpty(phone)) {
            User targetUser = userMapper.selectOne(new QueryWrapper<User>().eq(
                    "phone", phone));
            UserResponseVo userResponseVo = new UserResponseVo();
            BeanUtils.copyProperties(targetUser, userResponseVo);
            return userResponseVo;
        }
        return null;
    }

    /**
     * 修改用户信息
     *
     * @param requestBody 用户信息
     * @return 是否修改成功
     */
    @Override
    public boolean modifyInfo(Map<String, Object> requestBody) {
        User userObj = new User();
        BeanUtils.copyProperties(requestBody, userObj);
        int i = userMapper.updateById(userObj);
        return i > 0;
    }

    /**
     * 获取用户信息
     *
     * @param id 用户id
     * @return UserResponseVo
     */
    @Override
    public UserResponseVo getInfo(String id) {
        User user = userMapper.selectById(id);
        UserResponseVo userResponseVo = new UserResponseVo();
        BeanUtils.copyProperties(user, userResponseVo);
        return userResponseVo;
    }

    /**
     * 修改密码
     *
     * @param requestBody 用户、密码、新密码
     * @return 是否修改成功
     */
    @Override
    public boolean modifyPwd(Map<String, Object> requestBody) {
        // TODO: 修改密码 < 2021-01-29, farajmujey > 📣
        return false;
    }

    /**
     * 分页查询用户 每页10条记录
     *
     * @param current 当前页
     * @return UserPageVo
     */
    @Override
    public PageVo<UserResponseVo> page(int current) {
        IPage<User> page = new Page<>(current, 10);
        userMapper.selectPage(page, null);
        List<UserResponseVo> vos = page.getRecords().stream().map(e -> {
            UserResponseVo userResponseVo = new UserResponseVo();
            BeanUtils.copyProperties(e, userResponseVo);
            return userResponseVo;
        }).collect(Collectors.toList());
        return YsjUtil.pageFilling(current, 10, page.getTotal(), vos);
    }

    @Override
    public boolean isExist(String id) {
        User user = userMapper.selectById(id);
        return user != null;
    }

    /**
     * 判断手机号是否存在
     *
     * @param phone 手机号
     * @return R
     */
    @Override
    public R checkPhone(String phone) {
        User user = userMapper.selectOne(new QueryWrapper<User>()
                .eq("phone", phone));
        if (user != null) {
            return R.ok().detail(DetailSelector.QUERY_SUCCESS);
        } else {
            return R.err().detail(DetailSelector.QUERY_ERROR);
        }
    }

    /**
     * 创建新用户
     *
     * @param requestBody requestBody
     * @return boolean
     */
    @Override
    public String newUser(Map<String, Object> requestBody) {
        int i = -1;
        String id = null;
        // 手机号和用户名必须存在
        String phone = (String) requestBody.get("phone");
        String username = (String) requestBody.get("username");
        String email = (String) requestBody.get("email");
        if (stringsCompliant(phone, username, email)) {
            // 判断用户是否已经存在
            List<User> users = userMapper.selectList(new QueryWrapper<User>().eq(
                    "phone"
                    , phone));
            if (users.size() > 0) {
                throw new CasualException(5000, "手机号已被注册");
            }
            if (userMapper.selectList(new QueryWrapper<User>().eq("username",
                    username)).size() > 0) throw new CasualException(5000,
                    "用户名已被使用");
            if (userMapper.selectList(new QueryWrapper<User>().eq("email",
                    email)).size() > 0) throw new CasualException(5000,
                    "该邮箱已被使用");
            // 构建用户对象
            User user = new User();
            user.setPhone(phone);
            user.setUsername(username);
            String nickname = (String) requestBody.get("nickname");
            if (!StringUtils.isEmpty(nickname)) {
                user.setNickname(nickname);
            }
            Integer gender = (Integer) requestBody.get("gender");
            if (!StringUtils.isEmpty(gender)) {
                user.setGender(gender);
            }
            String summary = (String) requestBody.get("summary");
            if (!StringUtils.isEmpty(summary)) {
                user.setSummary(summary);
            }
            user.setEmail(email);
            String password = (String) requestBody.get("password");
            if (!StringUtils.isEmpty(password)) {
                user.setPassword(password);
            } else {
                user.setPassword(UUID.randomUUID().toString().replaceAll("-", "")
                        + UUID.randomUUID().toString().replaceAll("-", "")
                        + System.currentTimeMillis());
            }
            String avatar = (String) requestBody.get("avatar");
            if (!StringUtils.isEmpty(avatar)) {
                user.setAvatar(avatar);
            } else {
                user.setAvatar(DEFAULT_AVATAR_BASE_URL + "RANDOM_AVATAR_" + RandomUtils.nextInt(0, 51) + ".png");
            }
            i = userMapper.insert(user);
            id = user.getId();
        }
        return i > 0 ? id : null;
    }

    /*
        private methods
     */
    private void checkRequestBodyForPassword(Map<String, Object> requestBody) {
        boolean username = requestBody.containsKey("username");
        boolean password = requestBody.containsKey("password");
        if (!(username && password))
            throw new RequestBodyArgumentException(5000, "未找到用户名或密码");
    }

}
